/*********************************************************************************
 *      Copyright:  (C) Guo Zixuan
 *                  All rights reserved.
 *
 *       Filename:  parse_data.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(17/05/25)
 *         Author:  Guo Zixuan <guozixuan@gmail.com>
 *      ChangeLog:  1, Release initial version on "17/05/25 16:36:33"
 *                 
 ********************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/resource.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "logger.h"
#include "parse_data.h"

int parse_data(uint8_t *buf, data_t *data)
{
	int         k = 0;
	char        *str = NULL;

	if( !buf || !data )
	{
		log_warning("arguments is NULL");
		return -1;
	}

	str = strtok(buf, "=");
	while ( str )
	{   
		str = strtok(NULL, "\n");
		if ( k == 0 )
		{
			snprintf(data->sn, sizeof(data->sn), "%s", str);
		}
		else if ( k == 1 )
		{
			snprintf(data->mytime, sizeof(data->mytime), "%s", str);
		}
		else if ( k == 2)
		{

			float           temp_value = atof(str);
			snprintf(data->temp, sizeof(data->temp), "%.4f", temp_value);
		}
		++k;
		str = strtok(NULL, "=");
	}

	k = 0;
	return 0;
}

int parse_data_json(uint8_t *buf, data_t *data)
{
	int                     k = 0;
	char                   *str = NULL;

	if( !buf || !data )
	{
		log_warning("arguments is NULL");
		return -1;
	}

	str = strtok(buf, ":");
	while ( str )
	{
		str = strtok(NULL, "\"");
		if ( k == 0 )   
		{               
			snprintf(data->sn, sizeof(data->sn), "%s", str);
		}               
		else if (k == 1 )
		{               
			snprintf(data->mytime, sizeof(data->mytime), "%s", str);
		}               
		else if (k == 2)
		{ 
			float           temp_value = atof(str);
			snprintf(data->temp, sizeof(data->temp), "%.4f", temp_value);
		}
		++k;
		str = strtok(NULL, ":");
	}

	k = 0;
	return 0;
}

int parse_data_tlv(uint8_t *buf, data_t *data) 
{
	char        		*str = NULL;
	char            	temp_str[32];
	int                 tag_temperature = 1;
	uint16_t  			crc_check;

	if( !buf || !data )
	{
		log_warning("arguments is NULL");
		return -1;
	}

	//Header
	uint16_t header = ntohs(*(uint16_t *)buf);
	if ( header != 0xABCD )
	{
		log_error("Header failure\n");
		return -1;
	}

	//Tag
	uint8_t tag = buf[2];
	if ( tag != tag_temperature )
	{
		log_error("Tag failure\n");
		return -1;
	}

	//Length
	uint16_t length = (*(uint16_t *)(buf + 3));

	//Valure:sn
	char sn[10] = {0};
	memcpy(sn, buf + 5, 10);
	
	//Value:temp
	uint8_t temp_int = buf[15];
	uint8_t temp_decimal1 = buf[16];
	uint8_t temp_decimal2 = buf[17];
	
	//Valure:TIME
	uint8_t year = buf[18];                 // 年 - 2000
	uint8_t month = buf[19];                // 月
	uint8_t day = buf[20];                  // 日
	uint8_t hour = buf[21];                 // 时
	uint8_t minute = buf[22];               // 分
	uint8_t second = buf[23];               // 秒

	//CRC校验
	uint16_t crc = ntohs(*(uint16_t *)(buf + 24));
	crc_check = crc_itu_t(buf, length+5);
	if ( crc != crc_check )
	{
		log_error("CRC failure\nCRC16: 0x%04X\nCRC16_check: 0x%04X\n", crc, crc_check);
		return -1;
	}

	strncpy(data->sn, sn, sizeof(data->sn));
	snprintf(data->mytime, sizeof(data->mytime), 
			"%04d%02d%02d %02d:%02d:%02d",year + 2000, month, day, hour, minute, second);
	snprintf(data->temp, sizeof(data->temp), "%d.%02d%02d", temp_int, temp_decimal1, temp_decimal2);

	return 0;
}

static uint16_t crc_itu_t(const uint8_t *data, size_t length)
{
	uint16_t          crc = 0xFFFF;
	size_t            i, j;

	for (i=0; i<length; i++)
	{
		crc ^= ((uint16_t)data[i] << 8);

		for(j=0; j<8; j++)
		{
			if (crc & 0x8000)
			{
				crc = (crc << 1) ^ CRC16_ITU_T_POLY;
			}
			else
			{
				crc <<= 1;
			}
		}
	}

	return crc;
}
